
#include <Arduino.h>
#include "bus_can.h"

Bus_can::Bus_can(int test):can_dev(9),canutil(can_dev),i2c_io(MCP23008_ADDR)
{

}


void Bus_can::start()
{
     pinMode(3,INPUT);  // switch SW4 initiates a transmission, jumper JMP4 must be in position A

    i2c_io.Write(IOCON,0x04);    // makes I2C interrupt pin open-drain to allow sharing INT0 pin with MCP2510 without conflict

    canutil.setOpMode(4); // sets configuration mode
  // IMPORTANT NOTE: configuration mode is the ONLY mode where bit timing registers (CNF1, CNF2, CNF3), acceptance
  // filters and acceptance masks can be modified

  canutil.waitOpMode(4);  // waits configuration mode


  canutil.flashRxbf();  //just for fun!


  can_dev.write(CANINTE,0x01);  //disables all interrupts but RX0IE (received message in RX buffer 0)
  can_dev.write(CANINTF, 0x00);  // Clears all interrupts flags

  canutil.setClkoutMode(0,0);  // disables CLKOUT
  canutil.setTxnrtsPinMode(0,0,0);  // all TXnRTS pins as all-purpose digital input


  // Bit timing section
  //  setting the bit timing registers with Fosc = 16MHz -> Tosc = 62,5ns
  // data transfer = 125kHz -> bit time = 8us, we choose arbitrarily 8us = 16 TQ  (8 TQ <= bit time <= 25 TQ)
  // time quanta TQ = 2(BRP + 1) Tosc, so BRP =3
  // sync_seg = 1 TQ, we choose prop_seg = 2 TQ
  // Phase_seg1 = 7TQ yields a sampling point at 10 TQ (60% of bit length, recommended value)
  // phase_seg2 = 6 TQ SJSW <=4 TQ, SJSW = 1 TQ chosen
  can_dev.write(CNF1,0x03);  // SJW = 1, BRP = 3
  can_dev.write(CNF2,0b10110001);  //BLTMODE = 1, SAM = 0, PHSEG = 6, PRSEG = 1
  can_dev.write(CNF3, 0x05);  // WAKFIL = 0, PHSEG2 = 5



  // for buffer RXB0
  //canutil.setRxOperatingMode(3, 1, 0);  // mask off  and rollover
  canutil.setRxOperatingMode(1, 1, 0);  // standard ID messages only  and rollover

}


void Bus_can::setAcceptanceFilter(unsigned int stdID, unsigned long extID, uint8_t extended, uint8_t filter)
{
    canutil.setAcceptanceFilter(stdID, extID, extended, filter); // 0 <= stdID <= 2047, 0 <= extID <= 262143, 1 = extended, filter# 1
}


void Bus_can::setAcceptanceMask(unsigned int stdID, unsigned long extID, uint8_t buffer)
{
    canutil.setAcceptanceMask(stdID, extID, buffer); // 0 <= stdID <= 2047, 0 <= extID <= 262143, buffer# 0
}


void Bus_can::startFinished()
{
    canutil.setOpMode(0); // sets normal  mode

    canutil.setTxBufferDataLength(0,8,0);   // TX normal data, 1 byte long, with buffer 0

    isInt = 0; // resets interrupt flag
    can_dev.write(CANINTF, 0x00);  // Clears all interrupts flags

    delay(3000);
}


uint8_t Bus_can::whichOpMode()
{
    return canutil.whichOpMode();
}


void Bus_can::sendMsg(uint8_t *tosend)
{
    canutil.setTxBufferID(msgID,2000,0,0);  // sets the message ID, specifies standard message (i.e. short ID) with buffer 0

    canutil.setTxBufferDataField(tosend, 0);   // fills TX buffer

    canutil.messageTransmitRequest(0,1,3);  // requests transmission of buffer 0 with highest priority

    int timeout=0;
    do
    {
        txstatus = 0;
        txstatus = canutil.isTxError(0);  // checks tx error
        txstatus = txstatus + canutil.isArbitrationLoss(0);  // checks for arbitration loss
        txstatus = txstatus + canutil.isMessageAborted(0);  // ckecks for message abort
        txstatus = txstatus + canutil.isMessagePending(0);   // checks transmission

        timeout++;
    }
    while (txstatus != 0 && timeout<1000); // waits for no error condition  and time out

}


void Bus_can::readMsg()
{
  isInt = 0; // resets interrupt flag

  can_dev.write(CANINTF, 0x00);  // Clears all interrupts flags

  recSize =canutil.whichRxDataLength(0);  // checks the number of bytes received in buffer 0 (max = 8)

  for (int i=0; i<recSize; i++)
  {  // gets the bytes
    recData[i] = canutil.receivedDataValue(0,i);
  }

  isInt = 0;
}


void Bus_can::setMsgID(uint16_t id)
{
    msgID=id;
}


void Bus_can::setInt()
{
    isInt = 1;
}

void Bus_can::resetInt()
{
    isInt = 0;
}


int Bus_can::getIsInt()
{
  return isInt;
}


uint8_t Bus_can::getData(int i)
{
    return recData[i];
}


